package com.huatai.common.util;

/**
 * @program: ht-system
 * @description: 时间工具
 * @author: songxiude
 * @create: 2023-04-25 14:15
 **/
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;

/**
 * @program: ht-system
 * @description: 加密方式配置
 * @author: songxiude
 * @create: 2023-04-25 16:56
 **/
public class TimeUtil {

	private LocalDateTime localDateTime;

	public TimeUtil() {
		localDateTime = LocalDateTime.now();
	}

	public TimeUtil(LocalDateTime localDateTime) {
		this.localDateTime = localDateTime;
	}

	/**
	 * 创建对象
	 *
	 * @return 创建对象
	 */
	public static TimeUtil build() {
		return new TimeUtil();
	}

	/**
	 * 创建对象
	 *
	 * @param localDateTime 输入日期
	 * @return 创建对象
	 */
	public static TimeUtil build(LocalDateTime localDateTime) {
		return new TimeUtil(localDateTime);
	}

	/**
	 * 创建对象
	 *
	 * @param timestamp 时间戳
	 * @return 创建对象
	 */
	public static TimeUtil build(Long timestamp) {
		int length = String.valueOf(timestamp).length();
		LocalDateTime localDateTime;
		if (length == 10) {
			localDateTime = LocalDateTime.ofEpochSecond(timestamp, 0, ZoneOffset.ofHours(8));
		} else if (length == 13) {
			localDateTime = Instant.ofEpochMilli(timestamp).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
		} else {
			throw new IllegalArgumentException("error, Timestamp parsing failed !");
		}
		return new TimeUtil(localDateTime);
	}

	/**
	 * 创建对象
	 *
	 * @param format yyyy-MM-dd HH:mm:ss 日期类型
	 * @return 创建对象
	 */
	public static TimeUtil build(String format) {
		LocalDateTime parse = LocalDateTime.parse(format, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
		return new TimeUtil(parse);
	}

	/**
	 * 获取默认结果
	 *
	 * @return LocalDateTime类型结果
	 */
	public LocalDateTime result() {
		return localDateTime;
	}

	/**
	 * 获取默认结果
	 *
	 * @return LocalDateTime类型结果
	 */
	public LocalDateTime resultToLocalDateTime() {
		return localDateTime;
	}

	/**
	 * 获取秒级时间戳
	 *
	 * @return 毫秒时间戳
	 */
	public Long resultToSecond() {
		return localDateTime.toInstant(ZoneOffset.ofHours(8)).getEpochSecond();
	}

	/**
	 * 获取毫秒级时间戳
	 *
	 * @return 毫秒时间戳
	 */
	public Long resultToMillisecond() {
		return localDateTime.toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
	}


	/**
	 * ------------------------------- 今天/这个月/今年 ----------------------------------
	 */

	/**
	 * 获取今天的第一秒
	 */
	public TimeUtil getStartSecondOfDay() {
		firstSecond(LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MIN));
		return this;
	}

	/**
	 * 获取当天的最后一秒
	 */
	public TimeUtil getEndSecondOfDay() {
		lastSecond(LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MAX));
		return this;
	}

	/**
	 * 获取当前月份的第一秒
	 */
	public TimeUtil getStartSecondOfMonth() {
		firstSecond(localDateTime.with(TemporalAdjusters.firstDayOfMonth()));
		return this;
	}

	/**
	 * 获取输入月份的最后一秒
	 */
	public TimeUtil getEndSecondOfMonth() {
		lastSecond(localDateTime.with(TemporalAdjusters.lastDayOfMonth()));
		return this;
	}

	/**
	 * ------------------------------- 昨天/上个月/去年 ----------------------------------
	 */

	/**
	 * 获取昨天的第一秒
	 */
	public TimeUtil getStartSecondOfYesterday() {
		firstSecond(localDateTime.minusDays(1));
		return this;
	}

	/**
	 * 获取昨天的最后一秒
	 */
	public TimeUtil getEndSecondOfYesterday() {
		lastSecond(localDateTime.minusDays(1));
		return this;
	}

	/**
	 * 上个月最后一秒
	 */
	public TimeUtil getStartSecondOfLastMonth() {
		firstSecond(localDateTime.with(TemporalAdjusters.firstDayOfMonth()));
		return this;
	}

	/**
	 * 上个月最后一秒
	 */
	public TimeUtil getEndSecondOfLastMonth() {
		lastSecond(localDateTime.with(TemporalAdjusters.lastDayOfMonth()));
		return this;
	}


	/**
	 * -------------------------------------- 私有方法 --------------------------------------
	 */

	/**
	 * 获取开始时间 按照天计算
	 */
	private void firstSecond(LocalDateTime localDateTime){
		this.localDateTime = LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MIN);
	}

	/**
	 * 获取结束时间 按照天计算
	 */
	private void lastSecond(LocalDateTime localDateTime){
		this.localDateTime = LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MAX);
	}

}

